<?php
	
	namespace Aspic\Route;
	use Aspic as A;
	use Aspic\Security\Security as S;
	
	class RegexRoute extends AbstractRoute {
		
		protected $_pattern;
		protected $_fromRegex;
		protected $_matchesConnection;
		protected $_reverseStr;
		
		/**
		* Regex route
		* 
		* @param string $from The regex that wll parse the url 
		* (it is already surround with "#^" and "$#",  so you have to escape the # if you use it in your regex)
		* 
		* @param array $matchesConnection An array containing the corresponding string index for regex matches array.
		* ex: array(0 => 'firstParenthese', 1 => 'secondParenthese'). You may also used the (?P<paramName>.+) in your regex
		* 
		* @param string $fromArgsReverseStr The pattern that will be used to reverse the route (because reversing a regex is not an easy task)
		* fromArgs means that the string will be treated with UString::fromArgs() (sprintf like).
		* ex: "users/{userName}"
		*/
		public function __construct($pattern, $to, array $matchesConnection = array(), $reverseStr = null) {
			$this->_pattern = $pattern;
			$this->_fromRegex = '#\\A'.$pattern.'\\z#';
			$this->_to = $to;
			$this->_matchesConnection = $matchesConnection;
			$this->_reverseStr = $reverseStr;
			
			return $this;
		}
		
		public function match($src) {
			return (bool)preg_match($this->_fromRegex, $src);
		}
		
		public function parse($src) {
			preg_match($this->_fromRegex, $src, $regMatches);
			
			$actionPath = $this->_to;
//			$actionData = static::parseActionPath($actionPath);
			$actionData['data'] = static::parseActionPath($actionPath);
			
			$params = array_slice($regMatches, 1);
			
			foreach($this->_matchesConnection as $numericIndex => $index) {
				if(isset($params[$numericIndex])) {
					$params[$index] = $params[$numericIndex];
					unset($params[$numericIndex]);
				}
			}
			
			$actionData['params'] = $params;
			
			if(!$actionData) {
				$this->throwActionDataError();
			}
			else {	
				return $actionData;
			}
		}
		
		public function reverseRoute(array $params = array(), $encodeParams = true) {
			if(!$this->_reverseStr) {
				throw new Exception('No reverse pattern has been set for regex route: '.$this->_from);
			}
			else {
				if($encodeParams) {					
					$encodedParams = array();
					
					foreach($params as $k => $param) {
						$encodedParams[$k] = urlencode($param);
					}
					
					$params = $encodedParams;
				}
			
				$reversedRoute = A\UString::fromArgsArray($this->_reverseStr, $params, '?', ':', ':');
				
				return $reversedRoute;
			}
		}
		
	}
	
?>